#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
企业级Python函数最佳实践示例 - 对比Java方法

本文件演示了Python函数的企业级使用模式，特别针对Java工程师的理解需求：

学习重点：
1. Python函数 vs Java方法的区别
2. 动态参数 vs Java重载
3. 装饰器 vs Java注解
4. 函数式编程 vs Java Lambda
5. 类型注解 vs Java泛型

Java对比要点：
- Python函数是一等公民，可以作为变量传递（Java需要函数式接口）
- Python支持动态参数，Java需要方法重载
- Python装饰器类似Java注解但更强大
- Python支持闭包和高阶函数

作者: Python企业开发团队
创建时间: 2024-01-01
版本: 1.0.0
"""

# === 导入模块说明（对比Java import） ===
from typing import List, Dict, Callable, Optional, Union, Any, TypeVar, Generic  # 类似Java泛型
from functools import wraps, reduce, partial  # 函数工具，Java需要Stream API
from dataclasses import dataclass  # 数据类，类似Java record
import time     # 时间处理，类似Java的java.time
import logging  # 日志系统，类似Java的slf4j
from decimal import Decimal  # 精确小数，类似Java的BigDecimal
from enum import Enum        # 枚举类，类似Java的enum

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 类型变量定义
T = TypeVar('T')
Numeric = Union[int, float, Decimal]

class OperationType(Enum):
    """操作类型枚举"""
    ADD = "addition"
    SUBTRACT = "subtraction"
    MULTIPLY = "multiplication"
    DIVIDE = "division"

@dataclass
class CalculationResult:
    """计算结果数据类"""
    value: Numeric
    operation: OperationType
    operands: List[Numeric]
    timestamp: float

# 装饰器定义
def timing_decorator(func: Callable[..., T]) -> Callable[..., T]:
    """计时装饰器 - 测量函数执行时间
    
    Args:
        func: 被装饰的函数
        
    Returns:
        装饰后的函数
    """
    @wraps(func)
    def wrapper(*args: Any, **kwargs: Any) -> T:
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        execution_time = end_time - start_time
        logger.info(f"函数 {func.__name__} 执行时间: {execution_time:.4f} 秒")
        return result
    return wrapper

def validate_numeric(func: Callable[..., T]) -> Callable[..., T]:
    """数值验证装饰器
    
    Args:
        func: 被装饰的函数
        
    Returns:
        装饰后的函数
        
    Raises:
        TypeError: 当参数不是数值类型时
    """
    @wraps(func)
    def wrapper(*args: Any, **kwargs: Any) -> T:
        for arg in args:
            if not isinstance(arg, (int, float, Decimal)):
                raise TypeError(f"参数必须是数值类型，实际类型: {type(arg).__name__}")
        return func(*args, **kwargs)
    return wrapper

def retry(max_attempts: int = 3, delay: float = 1.0) -> Callable[[Callable[..., T]], Callable[..., T]]:
    """重试装饰器
    
    Args:
        max_attempts: 最大重试次数
        delay: 重试间隔（秒）
        
    Returns:
        装饰器函数
    """
    def decorator(func: Callable[..., T]) -> Callable[..., T]:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> T:
            last_exception = None
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    last_exception = e
                    if attempt < max_attempts - 1:
                        logger.warning(f"函数 {func.__name__} 第 {attempt + 1} 次尝试失败: {e}")
                        time.sleep(delay)
                    else:
                        logger.error(f"函数 {func.__name__} 所有重试均失败")
            raise last_exception
        return wrapper
    return decorator

# 全局函数定义
@timing_decorator
@validate_numeric
def add_numbers(x: Numeric, y: Numeric) -> Numeric:
    """安全的数值加法函数
    
    Args:
        x: 第一个数值
        y: 第二个数值
        
    Returns:
        两个数值的和
        
    Raises:
        TypeError: 当参数不是数值类型时
        
    Examples:
        >>> add_numbers(10, 20)
        30
        >>> add_numbers(3.14, 2.86)
        6.0
    """
    result = x + y
    logger.info(f"执行加法运算: {x} + {y} = {result}")
    return result

def calculate_with_validation(
    x: Numeric, 
    y: Numeric, 
    operation: OperationType = OperationType.ADD
) -> CalculationResult:
    """带验证的计算函数
    
    Args:
        x: 第一个操作数
        y: 第二个操作数
        operation: 操作类型
        
    Returns:
        计算结果对象
        
    Raises:
        ValueError: 当除数为零时
        TypeError: 当参数类型不正确时
    """
    if not isinstance(x, (int, float, Decimal)) or not isinstance(y, (int, float, Decimal)):
        raise TypeError("操作数必须是数值类型")
    
    if operation == OperationType.ADD:
        result = x + y
    elif operation == OperationType.SUBTRACT:
        result = x - y
    elif operation == OperationType.MULTIPLY:
        result = x * y
    elif operation == OperationType.DIVIDE:
        if y == 0:
            raise ValueError("除数不能为零")
        result = x / y
    else:
        raise ValueError(f"不支持的操作类型: {operation}")
    
    return CalculationResult(
        value=result,
        operation=operation,
        operands=[x, y],
        timestamp=time.time()
    )

def create_multiplier(factor: Numeric) -> Callable[[Numeric], Numeric]:
    """创建乘法器函数的工厂函数
    
    Args:
        factor: 乘法因子
        
    Returns:
        乘法器函数
    """
    def multiplier(value: Numeric) -> Numeric:
        return value * factor
    return multiplier

def demonstrate_basic_functions() -> None:
    """演示基础函数定义和类型注解 - 对比Java方法
    
    🎯 概述引导：
    Python函数是一等公民，这是与Java最大的区别之一。理解函数的灵活性是掌握Python的关键。
    
    📚 学习要点：
    1. Python函数可以独立存在，不需要类包装（Java方法必须在类中）
    2. 默认参数避免了Java的方法重载复杂性
    3. 函数可以作为变量传递和返回（Java需要函数式接口）
    4. 装饰器提供了比Java注解更强大的功能
    
    🔍 Java对比：
    public class Calculator {
        public double calculateTotalPrice(double price, double taxRate) {
            // Java需要在类中定义方法，Python函数可以独立存在
        }
        
        // Java方法重载（Python用默认参数代替）
        public double calculateTotalPrice(double price) {
            return calculateTotalPrice(price, 0.08);
        }
    }
    
    💡 关键理解：
    Python的函数式编程特性让代码更简洁，默认参数机制避免了Java的方法重载复杂性。
    """
    print("======== 1. 基础函数定义和类型注解 ========")
    print("🎯 学习目标：掌握Python函数的灵活性和与Java方法的根本差异")
    print("📖 重点概念：函数一等公民、默认参数、装饰器、可变参数")
    print("-" * 60)
    
    def calculate_total_price(price: float, tax_rate: float = 0.08) -> float:
        """计算含税总价 - 对比Java方法重载
        
        Java等价写法：
        public double calculateTotalPrice(double price, double taxRate) {
            if (price < 0) throw new IllegalArgumentException("价格不能为负数");
            if (taxRate < 0) throw new IllegalArgumentException("税率不能为负数");
            return Math.round((price * (1 + taxRate)) * 100.0) / 100.0;
        }
        
        Python优势：
        - 默认参数避免了Java的方法重载
        - 类型注解提供编译时提示（类似Java类型声明）
        - 函数可以独立存在，不需要类包装
        
        Args:
            price: 商品价格（类似Java的double price）
            tax_rate: 税率，默认8%（Java需要重载方法实现默认值）
            
        Returns:
            含税总价（类似Java的return double）
            
        Raises:
            ValueError: 当价格或税率为负数时（类似Java的IllegalArgumentException）
        """
        # === 参数验证（Java和Python类似） ===
        if price < 0:
            raise ValueError("价格不能为负数")  # 类似Java的 throw new IllegalArgumentException
        if tax_rate < 0:
            raise ValueError("税率不能为负数")
        
        # === 计算逻辑 ===
        total = price * (1 + tax_rate)
        return round(total, 2)  # Python内置round，Java需要Math.round
    
    # 演示基础函数使用
    try:
        # === 演示Python默认参数（对比Java方法重载） ===
        price1 = calculate_total_price(100.0)  # 使用默认税率
        price2 = calculate_total_price(100.0, 0.10)  # 指定税率
        print(f"✓ 默认税率计算: {price1}")
        print(f"✓ 指定税率计算: {price2}")
        
        # === 演示装饰器增强的函数 ===
        result1 = add_numbers(10, 20)
        print(f"✓ 加法结果: {result1}")
        
        calc_result = calculate_with_validation(15, 3, OperationType.MULTIPLY)
        print(f"✓ 计算结果: {calc_result.value} (操作: {calc_result.operation.value})")
        
    except Exception as e:
        logger.error(f"函数执行失败: {e}")

def demonstrate_advanced_parameters() -> None:
    """演示高级参数处理 - 对比Java的方法重载和可变参数
    
    Java对比：
    // Java需要多个重载方法或使用可变参数
    public Map<String, Object> createUserProfile(String name, int age, String... interests) {
        // Java的可变参数只支持同类型，不如Python灵活
    }
    
    // Java需要Builder模式处理复杂参数
    public class UserProfileBuilder {
        public UserProfileBuilder withMetadata(String key, Object value) { ... }
    }
    """
    print("\n======== 2. 高级参数处理 ========")
    
    def flexible_function(
        required_param: str,
        optional_param: Optional[str] = None,
        *args: Any,
        **kwargs: Any
    ) -> Dict[str, Any]:
        """演示灵活参数处理的函数 - 展示Python可变参数的强大功能
        
        Java等价写法需要多种方式组合：
        // 1. 可变参数（只能是最后一个参数，且类型相同）
        public Map<String, Object> flexibleMethod(String required, String optional, String... args)
        
        // 2. Builder模式处理复杂参数
        FlexibleBuilder.builder()
            .required(required)
            .optional(optional)
            .args(Arrays.asList(args))
            .metadata("key", "value")
            .build();
        
        Python优势：
        - *args: 可变位置参数，类似Java的String... args
        - **kwargs: 可变关键字参数，Java没有直接等价物
        - 更简洁的语法，无需Builder模式
        
        Args:
            required_param: 必需参数（类似Java的String required）
            optional_param: 可选参数（Java需要方法重载实现）
            *args: 可变位置参数（类似Java的String... args）
            **kwargs: 可变关键字参数（Java需要Map<String, Object>）
            
        Returns:
            包含所有参数信息的字典（类似Java的Map<String, Object>）
        """
        return {
            "required": required_param,
            "optional": optional_param,
            "args": args,
            "kwargs": kwargs
        }
    
    def process_data(
        data: List[T],
        processor: Callable[[T], T],
        filter_func: Optional[Callable[[T], bool]] = None,
        **options: Any
    ) -> List[T]:
        """通用数据处理函数
        
        Args:
            data: 要处理的数据列表
            processor: 处理函数
            filter_func: 可选的过滤函数
            **options: 额外选项
            
        Returns:
            处理后的数据列表
        """
        # 应用过滤器（如果提供）
        if filter_func:
            data = [item for item in data if filter_func(item)]
        
        # 应用处理函数
        processed_data = [processor(item) for item in data]
        
        # 处理额外选项
        if options.get("reverse", False):
            processed_data.reverse()
        
        if options.get("limit"):
            processed_data = processed_data[:options["limit"]]
        
        return processed_data
    
    # 演示使用
    result = flexible_function(
        "必需值",
        "可选值",
        "额外参数1",
        "额外参数2",
        key1="值1",
        key2="值2"
    )
    print(f"✓ 灵活参数函数结果: {result}")
    
    # 数据处理示例
    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    squared_evens = process_data(
        numbers,
        lambda x: x ** 2,
        lambda x: x % 2 == 0,
        reverse=True,
        limit=3
    )
    print(f"✓ 处理后的数据: {squared_evens}")

def compose_functions(
    func1: Callable[[T], T], 
    func2: Callable[[T], T]
) -> Callable[[T], T]:
    """函数组合器
    
    Args:
        func1: 第一个函数
        func2: 第二个函数
        
    Returns:
        组合后的函数
    """
    def composed(value: T) -> T:
        return func2(func1(value))
    return composed

def demonstrate_decorators() -> None:
    """演示装饰器的使用 - 对比Java注解和AOP
    
    Java对比：
    // Java需要AOP框架（如Spring AOP）或代理模式
    @Component
    public class UserService {
        @Timed  // 需要AspectJ或Spring AOP
        @Transactional
        public void processUser() {
            // 业务逻辑
        }
    }
    
    // 或者使用代理模式
    public class TimingProxy implements UserService {
        private UserService target;
        public void processUser() {
            long start = System.currentTimeMillis();
            target.processUser();
            long end = System.currentTimeMillis();
            System.out.println("执行时间: " + (end - start) + "ms");
        }
    }
    """
    print("\n======== 3. 装饰器和函数增强 ========")
    
    def enhanced_timing_decorator(func: Callable) -> Callable:
        """增强的计时装饰器 - 对比Java的AOP切面
        
        Java等价实现需要：
        1. Spring AOP + @Aspect注解
        2. 或者代理模式手动实现
        3. 或者AspectJ编译时织入
        
        Python装饰器优势：
        - 语法简洁，无需额外框架
        - 运行时动态修改函数行为
        - 可以嵌套使用多个装饰器
        - 保持原函数的元数据（通过@functools.wraps）
        """
        @wraps(func)  # 保持原函数元数据，类似Java的代理保持接口
        def wrapper(*args, **kwargs):
            # === 前置处理（类似Java AOP的@Before） ===
            start_time = time.time()
            print(f"开始执行函数: {func.__name__}")
            
            # === 执行原函数（类似Java AOP的ProceedingJoinPoint.proceed()） ===
            result = func(*args, **kwargs)
            
            # === 后置处理（类似Java AOP的@After） ===
            end_time = time.time()
            print(f"函数 {func.__name__} 执行时间: {end_time - start_time:.4f}秒")
            return result
        return wrapper
    
    # 演示装饰器使用
    @enhanced_timing_decorator
    def sample_function(n: int) -> int:
        """示例函数"""
        time.sleep(0.1)  # 模拟耗时操作
        return n * 2
    
    result = sample_function(5)
    print(f"✓ 装饰器增强函数结果: {result}")

def demonstrate_higher_order_functions() -> None:
    """演示高阶函数和函数式编程"""
    print("\n======== 4. 高阶函数和函数式编程 ========")
    
    # 演示闭包和工厂函数
    double = create_multiplier(2)
    triple = create_multiplier(3)
    
    print(f"✓ double(5) = {double(5)}")
    print(f"✓ triple(4) = {triple(4)}")
    
    # 演示函数组合
    add_ten = lambda x: x + 10
    multiply_by_two = lambda x: x * 2
    
    composed_func = compose_functions(add_ten, multiply_by_two)
    result = composed_func(5)  # (5 + 10) * 2 = 30
    print(f"✓ 组合函数结果: {result}")
    
    # 演示函数式编程技巧
    numbers = [1, 2, 3, 4, 5]
    
    # 使用 map, filter, reduce
    squared = list(map(lambda x: x ** 2, numbers))
    evens = list(filter(lambda x: x % 2 == 0, numbers))
    sum_all = reduce(lambda x, y: x + y, numbers)
    
    print(f"✓ 平方: {squared}")
    print(f"✓ 偶数: {evens}")
    print(f"✓ 总和: {sum_all}")
    
    # 使用 partial 函数
    multiply_by_10 = partial(lambda x, y: x * y, 10)
    result = multiply_by_10(5)
    print(f"✓ partial 函数结果: {result}")

@retry(max_attempts=2, delay=0.1)
def demonstrate_error_handling() -> None:
    """演示错误处理和重试机制"""
    print("\n======== 5. 错误处理和重试机制 ========")
    
    def safe_divide(x: Numeric, y: Numeric) -> Optional[Numeric]:
        """安全除法函数
        
        Args:
            x: 被除数
            y: 除数
            
        Returns:
            除法结果，如果除数为零则返回 None
        """
        try:
            if y == 0:
                logger.warning("尝试除以零，返回 None")
                return None
            return x / y
        except Exception as e:
            logger.error(f"除法运算出错: {e}")
            return None
    
    # 演示安全除法
    results = [
        safe_divide(10, 2),
        safe_divide(10, 0),
        safe_divide(15, 3)
    ]
    
    for i, result in enumerate(results):
        if result is not None:
            print(f"✓ 除法结果 {i+1}: {result}")
        else:
            print(f"✗ 除法结果 {i+1}: 操作失败")

def run_comprehensive_tests() -> None:
    """运行全面的函数测试套件"""
    print("\n======== 6. 综合测试套件 ========")
    
    test_cases = [
        ("基础加法", lambda: add_numbers(10, 20), 30),
        ("乘法计算", lambda: calculate_with_validation(6, 7, OperationType.MULTIPLY).value, 42),
        ("高阶函数", lambda: create_multiplier(5)(4), 20),
    ]
    
    passed_tests = 0
    total_tests = len(test_cases)
    
    for test_name, test_func, expected in test_cases:
        try:
            result = test_func()
            if result == expected:
                print(f"✓ {test_name} 测试通过")
                passed_tests += 1
            else:
                print(f"✗ {test_name} 测试失败: 期望 {expected}, 实际 {result}")
        except Exception as e:
            print(f"✗ {test_name} 测试异常: {e}")
    
    print(f"\n测试结果: {passed_tests}/{total_tests} 通过")
    print("所有企业级函数最佳实践演示完成!")

if __name__ == "__main__":
    demonstrate_basic_functions()
    demonstrate_advanced_parameters()
    demonstrate_decorators()
    demonstrate_higher_order_functions()
    demonstrate_error_handling()
    run_comprehensive_tests()